import axios from 'axios'
import { BASE_URL, TIME_OUT } from './config'

class ltRequest {
  constructor(config) {
    this.instance = axios.create(config)
    this.pendingRequests = {}
    // 初始化拦截器
    this.initInterceptors()
  }

  initInterceptors() {
    this.instance.interceptors.request.use(
      (config) => {
        this.removePendingRequest(config) // 检查是否存在重复请求，若存在则取消已发的请求
        this.addPendingRequest(config) // 把当前请求信息添加到pendingRequests对象中
        return config
      },
      (error) => {
        return Promise.reject(error)
      }
    )

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response) => {
        // 对响应数据做点什么
        this.removePendingRequest(response.config) // 响应成功，移除pendingRequests中的该请求
        return response.data
      },
      (error) => {
        if (error.config) {
          this.removePendingRequest(error.config) // 响应失败，移除pendingRequests中的该请求
        }
        return Promise.reject(error)
      }
    )
  }

  generateReqKey(config) {
    const { method, url, params, data } = config
    return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
  }

  addPendingRequest(config) {
    const requestKey = this.generateReqKey(config)
    config.cancelToken =
      config.cancelToken ||
      new axios.CancelToken((cancel) => {
        if (!this.pendingRequests[requestKey]) {
          this.pendingRequests[requestKey] = cancel
        }
      })
  }

  removePendingRequest(config) {
    const requestKey = this.generateReqKey(config)
    if (this.pendingRequests[requestKey]) {
      const cancel = this.pendingRequests[requestKey]
      cancel(requestKey)
      delete this.pendingRequests[requestKey]
    }
  }

  request(config) {
    return this.instance.request(config)
  }

  get(url, params, config) {
    return this.request({ ...config, method: 'GET', url, params })
  }

  post(url, data, config) {
    return this.request({ ...config, method: 'POST', url, data })
  }

  put(url, data, config) {
    return this.request({ ...config, method: 'PUT', url, data })
  }

  delete(url, params, config) {
    return this.request({ ...config, method: 'DELETE', url, params })
  }

  patch(url, data, config) {
    return this.request({ ...config, method: 'PATCH', url, data })
  }
}

// 创建请求实例
const request = new ltRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
})

export default request
